package com.ow.dva.module.base.controller;

import cn.hutool.crypto.digest.MD5;
import com.ow.dva.config.constant.UserConstant;
import com.ow.dva.config.shiro.ShiroAccount;
import com.ow.dva.module.base.entity.json.RT;
import com.ow.dva.module.account.entity.AccountAdmin;
import com.ow.dva.module.account.service.AccountAdminService;
import com.ow.dva.module.account.service.AccountInfoService;
import com.ow.dva.module.account.service.AccountService;
import com.ow.dva.module.permission.entity.Permission;
import com.ow.dva.module.permission.service.PermissionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.List;


/**
 * 描述 :
 * 包名 : com.ow.dva.module.base.service.impl
 * 作者 : GaoXiang
 * 时间 : 19-12-23
 * 版本 : V1.0
 */
@Controller
@RequestMapping(value = "/login")
@Api(tags = "登录相关")
public class LoginController extends BaseController{


    @GetMapping(value="/")
    public String adminLoginPage(){
        return "login";
    }

    @GetMapping(value="/permission")
    public String permission(){
        return "body/permission";
    }

    @ApiOperation(value = "管理员登录",notes = "管理员执行登 录操作")
    @PostMapping(value="/adminLogin")
    @ResponseBody
    public RT adminLogin(String userName,String password, HttpSession session){
        if(!userName.isEmpty() && !password.isEmpty()){
            //获取当前会话主体
            Subject subject = SecurityUtils.getSubject();
            //获取token
            UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
            try {
                //登陆
                subject.login(token);
            } catch (UnknownAccountException e) {
                return RT.error(1,"您的账号不存在！");
            }catch (IncorrectCredentialsException e) {
                return RT.error(2,"您的账号/密码 错误！");
            }catch (LockedAccountException e) {
                return RT.error(4,"您的账号账户已禁用！");
            } catch (AuthenticationException e) {
                return RT.error(3,"您的账号没有权限登录此平台！");
            }
            //如果登陆成功
            if (subject.isAuthenticated()) {
                ShiroAccount shiroAccount = (ShiroAccount) subject.getPrincipal();
                initSession(session, shiroAccount);
                initPermission(session, shiroAccount);
                return RT.ok("登录成功！");
            }
        }
        return RT.error(10,"登录失败！");
    }

    /**
     * 用户信息存入session
     */
    private void initSession(HttpSession session,ShiroAccount shiroAccount) {

        //存入用户
        session.setAttribute(UserConstant.ACCOUNT,shiroAccount.getAccount());

        //存入accountInfo
        if(shiroAccount.getAccountInfo() != null){
            session.setAttribute(UserConstant.ACCOUNT_INFO,shiroAccount.getAccountInfo());
        }

        //存入accountAdmin
        AccountAdmin accountAdmin = accountAdminService.findByAccountId(shiroAccount.getAccount().getId());
        if(accountAdmin != null){
            session.setAttribute(UserConstant.ACCOUNT_ADMIN,accountAdmin);
        }
    }

    /**
     * 初始化权限信息
     */
    public void initPermission(HttpSession session,ShiroAccount shiroAccount){
        List<Permission> list = permissionService.selectByAccountId(shiroAccount.getId());
        session.setAttribute(UserConstant.PERMISSION_LIST,list);
    }

    /**
     * 加密字符串 （网页javascript加密有加载延迟）
     * @param pwd 密码
     * @return 加密结果
     */
    @ApiOperation(value = "密码MD5加密",notes = "位密码执行加密操作")
    @PostMapping(value="/md5")
    @ResponseBody
    public String md5(String pwd){
        if(pwd != null && !"".equals(pwd)){
            return new MD5().digestHex(pwd);
        }
        return "";
    }

    /**
     * 注销登陆
     * @return sussess 成功 ，code = 1 失败
     */
    @ApiOperation(value = "账户退出登录",notes = "位密码执行加密操作")
    @GetMapping(value="/logout")
    public String logout(HttpSession session){
        try {
            session.removeAttribute(UserConstant.ACCOUNT);
            session.removeAttribute(UserConstant.ACCOUNT_ADMIN);
            session.removeAttribute(UserConstant.ACCOUNT_INFO);
            session.removeAttribute(UserConstant.PERMISSION_LIST);
            Subject subject = SecurityUtils.getSubject();
            subject.logout();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "redirect:/login/";
    }


    @Resource
    private AccountService accountService;

    @Resource
    private AccountInfoService accountInfoService;

    @Resource
    private AccountAdminService accountAdminService;

    @Resource
    PermissionService permissionService;
}
